/*
	Copyright (c) 2010 <copyright holders>
	This source code is licensed under The MIT License,
	see the file LICENSE for details.
	*/

#ifndef PROJECTILE_HPP
#define PROJECTILE_HPP

#include "ForwardDecls.hpp"
#include "Spatial.hpp"

namespace spelprog2 {
namespace sim {

const Int PROJECTILE_GRAVITY = 100;

/** Fairly simple class that handles a damage doing projectile that obeys gravity.

    Implementation notes:
    Projectile does not know about what fired it.
    No world reference is stored as this object is small enough to be allocated
    directly in a list; instead it gets a reference through update function.
    O(n^2) deletion is avoided thru simUpdate() returning a "keep alive" value.
    */
class Projectile {
    const ProjectileInvariant * invariant_; //must be pointer rather than ref to make class assignable
    Int3d position_;
    Int3d velocity_;
    Int healthDamage_;
    Int moraleDamage_;
    Int id_;

    Projectile(const ProjectileInvariant & invariant, const Int3d & initPosition,
        const Int3d & initVelocity, Int healthDamage, Int moraleDamage);
public:
    static Projectile & create(World & world, const ProjectileInvariant & invariant, const Int3d & initPosition,
        const Int3d & initVelocity, Int healthDamage, Int moraleDamage);

    void setId(Int id) { id_ = id; }
    const Int getId() const { return id_; }

    const Int3d & getPosition() const { return position_; }

    const ProjectileInvariant & getInvariant() const { return *invariant_; }

    //! Update function. Returns true if projectile should still exist after update.
    bool simUpdate(World & world, Int sequenceNbr);
};

}; //sim
}; //spelprog2

#endif //PROJECTILE_HPP
